package ui;

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.TimeZone;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.InputVerifier;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;

import entity.Event;
import entity.ICalendar;

/**
 * A Panel that contains the options to create and add
 * a calendar to the list.
 * 
 * @author Sean Young
 * @version 1.0
 *
 */
public class CreateCalendar extends JPanel implements ActionListener{
	private JPanel calendarName, version, tzidPanel, tzidOther, tzidDefault, buttonPanel;
	private JTextField calendarNameText, versionText;
	private JLabel tzidValidationLabel;
	private AutoSuggest timezoneID;
	private JRadioButton defaultTZ, otherTZ;
	private JButton addCal, discardCal;
	private boolean validTZID = true;
	
	private CalendarUI parent;
	private CalendarPanelListener listener;
	private TZIDVerifier tzidVerifier;
	
	/**
	 * Constructor for the CreateCalendar panel.
	 * @param parent The Main Panel of the CalendarUI
	 */
	public CreateCalendar(CalendarUI parent) {
		super();
		setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
		this.parent = parent;
		listener = new CalendarPanelListener();
		
		calendarName = new JPanel(new FlowLayout(FlowLayout.LEFT));
		calendarNameText = new JTextField(50);
		calendarNameText.setText("Untitled Calendar");
		calendarName.add(calendarNameText);
		add(calendarName);
		
		version = new JPanel(new FlowLayout(FlowLayout.LEFT));
		versionText = new JTextField(5);
		versionText.setText("2.0");
		version.add(new JLabel("Version"));
		version.add(versionText);
		add(version);
		
		String[] allTimeZones = TimeZone.getAvailableIDs();
		List<String> tzids = Arrays.asList(allTimeZones);
		tzidPanel = new JPanel();
		tzidPanel.setLayout(new BoxLayout(tzidPanel, BoxLayout.PAGE_AXIS));
		tzidPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.BLACK),"Time Zone Identifier"));
		
		tzidDefault = new JPanel(new FlowLayout(FlowLayout.LEFT));
		
		defaultTZ = new JRadioButton();
		defaultTZ.setActionCommand("defaultTZ");
		defaultTZ.addActionListener(this);
		defaultTZ.setSelected(true);
		
		tzidDefault.add(defaultTZ);
		tzidDefault.add(new JLabel("Default: " + TimeZone.getDefault().getID()));
		tzidPanel.add(tzidDefault);
		
		tzidOther = new JPanel(new FlowLayout(FlowLayout.LEFT));
		timezoneID = new AutoSuggest(new ArrayList<String>(tzids));
		timezoneID.textField.setEnabled(false);
		tzidVerifier = new TZIDVerifier();
		
		timezoneID.textField.addActionListener(tzidVerifier);
		timezoneID.textField.setInputVerifier(tzidVerifier);
		
		otherTZ = new JRadioButton();
		otherTZ.setActionCommand("otherTZ");
		otherTZ.addActionListener(this);
		tzidOther.add(otherTZ);
		tzidOther.add(timezoneID);
		tzidValidationLabel = new JLabel("   ");
		tzidValidationLabel.setForeground(Color.RED);
		tzidOther.add(tzidValidationLabel);
		tzidPanel.add(tzidOther);
		
		ButtonGroup tzidButtons = new ButtonGroup();
		tzidButtons.add(defaultTZ);
		tzidButtons.add(otherTZ);
		add(tzidPanel);
		
		buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
		addCal = new JButton("Add Calendar");
		discardCal = new JButton("Discard");
		discardCal.setActionCommand("discard");
		discardCal.addActionListener(listener);
		
		addCal.setActionCommand("addCal");
		addCal.addActionListener(listener);
		buttonPanel.add(addCal);
		buttonPanel.add(discardCal);
		add(buttonPanel);
	}
	
	/**
	 * Resets the CreateCalendar panel.
	 */
	public void reset() {
		calendarNameText.setText("Untitled Calendar");
		versionText.setText("2.0");
		defaultTZ.setSelected(true);
		tzidValidationLabel.setText("   ");
		timezoneID.textField.setText("");
		validTZID = true;
		timezoneID.textField.setEnabled(false);
	}
	
	/**
	 * Builds an ICalendar using the values contained in the
	 * fields of the Panel.
	 * @return An ICalendar with the specified properties
	 */
	public ICalendar buildCalendar() {
		ICalendar cal = new ICalendar(calendarNameText.getText());
		cal.setVersion(versionText.getText());
		
		if(otherTZ.isSelected() && ((!validTZID) || timezoneID.textField.getText().equals(""))) {
			JOptionPane.showMessageDialog(this, "Calendar not added.\nInvalid TZID.");
			return null;
		} else {
			cal.setTZID(timezoneID.textField.getText());
		}
		System.out.println("TEXT:" +  timezoneID.textField.getText());
		JOptionPane.showMessageDialog(this, "Calendar: " + cal.getName() + " added.");
		return cal;
	}
	
	/**
	 * Disables the "other" timezoneID field when the default is selected
	 * and enables the field when selected.
	 */
	public void actionPerformed(ActionEvent e) {
		switch(e.getActionCommand()) {
			case "defaultTZ": timezoneID.textField.setEnabled(false);
						      timezoneID.textField.setText("");
			 				  tzidValidationLabel.setText("   ");
							  break;
			case "otherTZ":   timezoneID.textField.setEnabled(true);
							  timezoneID.textField.setText("");
							  tzidValidationLabel.setText("   ");
							  break;
		}
	}
	
	/**
	 * Listener that creates an ICalendar or clears the fields based
	 * upon the button pressed.
	 * 
	 */
	public class CalendarPanelListener implements ActionListener{
		
		@Override
		public void actionPerformed(ActionEvent e) {
			
			Event event = new Event();
			
			switch(e.getActionCommand()){
				case "addCal" :  ICalendar c = buildCalendar();
								 if(c != null) {
									 parent.addCalendar(c);
								 }
								 parent.refreshCalPanel();
								 reset();
								 break;
				case "discard" : reset();
								 break;
										  
			}
		}	
	}
	
	/**
	 * Methods that verify the input of the TZID field.
	 */
	public class TZIDVerifier extends InputVerifier implements ActionListener {
		
		/**
		 * Verifies the validity of the TZID field by checking
		 * the following conditions.
		 */
		@Override
		public boolean verify(JComponent comp) {
			
			String[] allTimeZones = TimeZone.getAvailableIDs();
			List<String> tzids = Arrays.asList(allTimeZones);
			if(((JTextField)comp).getText().equals("")) {
				tzidValidationLabel.setText("TZID cannot be empty.");
				return false;
			}
			
			if(!(tzids.contains(((JTextField)comp).getText()))) {
				tzidValidationLabel.setText("Valid TZID not Found.");
				return false;
			}
			return true;
		}
		
		/**
		 * Returns whether the component should yield focus
		 * to other components. It will always evaluate to
		 * true to allow user to manipulate other fields
		 */	
		public boolean shouldYieldFocus(JComponent comp) {
			boolean inputOK = verify(comp);
			if(inputOK) {
				tzidValidationLabel.setText("    ");
				((JTextField) comp).setBackground(Color.WHITE);
				validTZID = true;
				return true;
			} else {
				((JTextField) comp).setBackground(Color.PINK);
				validTZID = false;
				return true;
			}
		}
		
		/**
		 * Performs the validation operations upon detecting
		 * an ActionEvent.
		 */
		public void actionPerformed(ActionEvent e) {
			JTextField source = (JTextField) e.getSource();
			shouldYieldFocus(source);
			source.selectAll();
		}
	}
	
}
